package org.example.MedicalCrowdsourcing.service;

import org.example.MedicalCrowdsourcing.model.entity.LoginRecord;
import org.example.MedicalCrowdsourcing.model.entity.Role;
import org.example.MedicalCrowdsourcing.model.entity.User;
import org.example.MedicalCrowdsourcing.repository.LoginRecordRepository;
import org.example.MedicalCrowdsourcing.repository.RoleRepository;
import org.example.MedicalCrowdsourcing.repository.UserRepository;
import org.example.MedicalCrowdsourcing.security.JwtUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 用户服务
 */
@Service
public class UserService implements UserDetailsService {
    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private LoginRecordRepository loginRecordRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private AuthenticationManager authenticationManager;
    
    @Autowired
    private JwtUtils jwtUtils;

    /**
     * 通过用户名查找用户
     */
    public Optional<User> findByUsername(String username) {
        return userRepository.findByUsername(username);
    }

    /**
     * 检查用户名是否存在
     */
    public boolean existsByUsername(String username) {
        return userRepository.existsByUsername(username);
    }

    /**
     * 检查邮箱是否存在
     */
    public boolean existsByEmail(String email) {
        return userRepository.existsByEmail(email);
    }

    /**
     * 注册新用户
     */
    @Transactional
    public User registerUser(String username, String email, String password, String roleName, String blockchainAddress) {
        // 创建新用户
        User user = new User();
        user.setUsername(username);
        user.setEmail(email);
        user.setPassword(passwordEncoder.encode(password));
        user.setBlockchainAddress(blockchainAddress);
        user.setCreatedAt(LocalDateTime.now());

        // 设置角色
        Role role = roleRepository.findByName(roleName);
        if (role == null) {
            // 如果角色不存在，使用参与者角色作为默认值
            role = roleRepository.findById(Role.PARTICIPANT)
                    .orElseThrow(() -> new RuntimeException("默认角色不存在"));
        }
        user.setRole(role);

        // 保存用户
        return userRepository.save(user);
    }

    /**
     * 记录用户登录
     */
    @Transactional
    public LoginRecord recordLogin(User user, HttpServletRequest request, boolean successful) {
        LoginRecord loginRecord = new LoginRecord();
        loginRecord.setUser(user);
        loginRecord.setIpAddress(getClientIp(request));
        loginRecord.setUserAgent(request.getHeader("User-Agent"));
        loginRecord.setSuccessful(successful);

        loginRecord = loginRecordRepository.save(loginRecord);

        // 更新用户最后登录时间
        if (successful) {
            user.setLastLogin(LocalDateTime.now());
            userRepository.save(user);
        }

        return loginRecord;
    }

    /**
     * 获取用户登录历史
     */
    public List<LoginRecord> getUserLoginHistory(User user) {
        return loginRecordRepository.findByUserOrderByLoginTimeDesc(user);
    }

    /**
     * 获取用户最近10次登录记录
     */
    public List<LoginRecord> getRecentLoginHistory(User user) {
        return loginRecordRepository.findTop10ByUserOrderByLoginTimeDesc(user);
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIp(HttpServletRequest request) {
        String remoteAddr = "";

        if (request != null) {
            remoteAddr = request.getHeader("X-FORWARDED-FOR");
            if (remoteAddr == null || remoteAddr.isEmpty()) {
                remoteAddr = request.getRemoteAddr();
            }
        }

        return remoteAddr;
    }

    /**
     * 用户注册
     * @param username 用户名
     * @param password 密码
     * @param email 邮箱
     * @param role 角色名称
     * @return 注册结果
     */
    public Map<String, Object> register(String username, String password, String email, String role) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 检查用户名是否已存在
            if (existsByUsername(username)) {
                result.put("success", false);
                result.put("message", "用户名已存在");
                return result;
            }
            
            // 检查邮箱是否已存在
            if (existsByEmail(email)) {
                result.put("success", false);
                result.put("message", "邮箱已存在");
                return result;
            }
            
            // 注册用户
            User user = registerUser(username, email, password, role, null);
            
            result.put("success", true);
            result.put("user", user);
            result.put("message", "注册成功");
            
        } catch (Exception e) {
            logger.error("注册失败", e);
            result.put("success", false);
            result.put("message", "注册失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 用户登录
     * @param username 用户名
     * @param password 密码
     * @return 登录结果，包含JWT令牌
     */
    public Map<String, Object> login(String username, String password) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 认证用户
            Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(username, password));
            
            // 获取用户信息
            User user = findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
            
            // 生成JWT令牌
            String token = jwtUtils.generateJwtToken(authentication);
            
            // 记录登录信息
            result.put("success", true);
            result.put("token", token);
            result.put("user", user);
            result.put("message", "登录成功");
            
        } catch (Exception e) {
            logger.error("登录失败", e);
            result.put("success", false);
            result.put("message", "登录失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 初始化角色数据
     * @return 初始化结果
     */
    public Map<String, Object> initRoles() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 检查角色是否已存在
            if (roleRepository.count() > 0) {
                result.put("success", true);
                result.put("message", "角色已初始化");
                return result;
            }
            
            // 创建角色
            roleRepository.save(new Role(Role.RESEARCHER, "RESEARCHER", "研究者"));
            roleRepository.save(new Role(Role.PARTICIPANT, "PARTICIPANT", "参与者"));
            roleRepository.save(new Role(Role.ADMIN, "ADMIN", "管理员"));
            
            result.put("success", true);
            result.put("message", "角色初始化成功");
            
        } catch (Exception e) {
            logger.error("角色初始化失败", e);
            result.put("success", false);
            result.put("message", "角色初始化失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取所有用户
     * @return 用户列表
     */
    public List<User> findAll() {
        return userRepository.findAll();
    }

    /**
     * 根据ID查找用户
     * @param id 用户ID
     * @return 用户对象
     */
    public Optional<User> findById(Long id) {
        return userRepository.findById(id);
    }

    /**
     * 记录用户登录信息
     * @param user 用户对象
     * @param ip IP地址
     * @param userAgent 用户代理
     * @param success 是否成功
     */
    public void recordLogin(User user, String ip, String userAgent, boolean success) {
        LoginRecord loginRecord = new LoginRecord();
        loginRecord.setUser(user);
        loginRecord.setIpAddress(ip);
        loginRecord.setUserAgent(userAgent);
        loginRecord.setSuccessful(success);
        
        loginRecordRepository.save(loginRecord);
        
        if (success) {
            user.setLastLogin(LocalDateTime.now());
            userRepository.save(user);
        }
    }

    /**
     * 保存用户信息
     * @param user 用户对象
     * @return 保存后的用户对象
     */
    @Transactional
    public User save(User user) {
        return userRepository.save(user);
    }

    /**
     * 删除用户
     * @param user 用户对象
     */
    @Transactional
    public void delete(User user) {
        userRepository.delete(user);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + username));
        
        return UserDetailsImpl.build(user);
    }
} 